📚 Zusammenfassung - Pointer-Arithmetik
- p + n: Springt n Elemente vorwärts (nicht n Bits)
- p - n: Springt n Elemente rückwärts
- ++p / --p: Präinkrement/-dekrement
- p[i]: Äquivalent zu *(p + i)
- p1 < p2, p1 > p2, p1 == p2: Pointer-Vergleich
- p2 - p1: Anzahl der Elemente zwischen den Pointern
- Wichtig: Pointer-Arithmetik berücksichtigt automatisch die Größe des Datentyps!
Schritt 1:
int arr[5] = {10, 20, 30, 40, 50};
int* p = &arr;
int* p = &arr;
| Variable | Adresse | Wert | Zeigt auf |
|---|---|---|---|
| arr[0] | 0x1000 | — | |
| arr[1] | 0x1004 | — | |
| arr[2] | 0x1008 | — | |
| arr[3] | 0x100c | — | |
| arr[4] | 0x1010 | — | |
| p | 0x2000 |
💡 Hinweis: Array-Elemente vom Typ int haben je 4 Bytes = 32 Bits. Die Adressen sind daher jeweils +0x0004 (4 Bytes) voneinander entfernt.
Frage 1: Was ist der Wert von *p?
cout << *p << endl;
| Ausdruck | Ergebnis |
|---|---|
| *p |
💡 Hinweis: *p dereferenziert den Pointer und gibt den Wert an der Adresse zurück, auf die p zeigt.
Frage 2: Was ist der Wert von *(p + 2)?
cout << *(p + 2) << endl;
| Ausdruck | Ergebnis |
|---|---|
| *(p + 2) |
💡 Hinweis: p + 2 springt 2 Elemente weiter (nicht 2 Bytes!). Von arr[0] zu arr[2].
Frage 3: Was ist der Wert von p[3]?
cout << p[3] << endl;
| Ausdruck | Ergebnis |
|---|---|
| p[3] |
💡 Hinweis: p[3] ist äquivalent zu *(p + 3). Array-Notation funktioniert auch mit Pointern!
Schritt 2:
++p;
| Variable | Adresse | Wert | Zeigt auf |
|---|---|---|---|
| arr[0] | 0x1000 | 10 | — |
| arr[1] | 0x1004 | 20 | — |
| arr[2] | 0x1008 | 30 | — |
| arr[3] | 0x100c | 40 | — |
| arr[4] | 0x1010 | 50 | — |
| p | 0x2000 |
💡 Hinweis: ++p erhöht die Adresse um sizeof(int) = 4 bytes = 32 Bits. p zeigt jetzt auf arr[1].
Frage 5: Was ist jetzt der Wert von *p?
cout << *p << endl; // nach ++p
| Ausdruck | Ergebnis |
|---|---|
| *p |
💡 Hinweis: Nach p++ zeigt p auf arr[1], also ist *p = 20.
Schritt 3:
p += 2;
| Variable | Adresse | Wert | Zeigt auf |
|---|---|---|---|
| arr[0] | 0x1000 | 10 | — |
| arr[1] | 0x1004 | 20 | — |
| arr[2] | 0x1008 | 30 | — |
| arr[3] | 0x100c | 40 | — |
| arr[4] | 0x1010 | 50 | — |
| p | 0x2000 |
💡 Hinweis: p += 2 springt 2 Elemente weiter. Von arr[1] (nach p++) zu arr[3]. Adresse: 0x1004 + 8 = 0x100c.
Schritt 4:
--p;
| Variable | Adresse | Wert | Zeigt auf |
|---|---|---|---|
| arr[0] | 0x1000 | 10 | — |
| arr[1] | 0x1004 | 20 | — |
| arr[2] | 0x1008 | 30 | — |
| arr[3] | 0x100c | 40 | — |
| arr[4] | 0x1010 | 50 | — |
| p | 0x2000 |
💡 Hinweis: --p springt 1 Element zurück. Von arr[3] (nach p += 2) zu arr[2]. Adresse: 0x100c - 4 = 0x1008.
Schritt 5:
*p = 100;
| Variable | Wert nach *p = 100 |
|---|---|
| arr[0] | |
| arr[1] | |
| arr[2] | |
| arr[3] | |
| arr[4] |
💡 Hinweis: p zeigt auf arr[2] (nach --p), also ändert *p = 100 den Wert von arr[2] auf 100.
Frage 9: Pointer-Vergleich
int* p1 = &arr[1];
int* p2 = &arr[3];
cout << (p1 < p2) << endl;
cout << (p2 > p1) << endl;
cout << (p1 == &arr[1]) << endl;
int* p2 = &arr[3];
cout << (p1 < p2) << endl;
cout << (p2 > p1) << endl;
cout << (p1 == &arr[1]) << endl;
| Ausdruck | Ergebnis (true/false) |
|---|---|
| p1 < p2 | |
| p1 == &arr[1] |
💡 Hinweis: Pointer können verglichen werden! p1 (Adresse 0x001020) < p2 (Adresse 0x001060) ist true (1). p1 zeigt auf arr[1], also ist p1 == &arr[1] true.
Frage 10: Pointer-Differenz
int* p1 = &arr[1];
int* p2 = &arr[4];
cout << (p2 - p1) << endl;
int* p2 = &arr[4];
cout << (p2 - p1) << endl;
| Ausdruck | Ergebnis |
|---|---|
| p2 - p1 |
💡 Hinweis: Pointer-Differenz gibt die Anzahl der Elemente zwischen den Pointern zurück, nicht die Differenz in Bytes! Von arr[1] zu arr[4] sind es 3 Elemente.